import React, { useEffect, useState, useCallback } from 'react'
import { connect } from 'react-redux'
import { NotifyType, RecordMode, SuiteLevel } from '../../common/enums'
import {
  getSuiteActiveSuiteIdSelector, getSuiteForceReloadIndexSelector,
  getActivePageOfActiveTabSelector, getSuiteActiveSuiteSelector, getSuiteActiveSuiteModeSelector,
} from '../../selectors/baseSelector'
import { genSuiteSetActiveSuite } from '../../actions/home'
import { SingleSelectableList } from '../layout/singleSelectableList'
import { getAllSuitesOfPage } from '../../source/getData'
import { notify } from '../../source/notify'
import { genTempId } from '../../source/genTempId'
import { Msgs } from '../../consts/msgs'
import basicStyle from '../common/basic.scss'
import { EmptyElement } from '../common/emptyElement'
import { mergeStyle } from '../common/mergeStyle'
import classnames from 'classnames'
import { Input } from '../common/Input'
import { SuiteLevelSelector } from '../common/suiteLevelSelector'
import { ColHeader } from '../common/colHeader'
import { withSignal } from '../../common/withSignal';

const maStateToProps = state => {
  return {
    forceReloadIndex: getSuiteForceReloadIndexSelector(state),
    activePage: getActivePageOfActiveTabSelector(state),
    activeSuiteId: getSuiteActiveSuiteIdSelector(state),
    activeSuite: getSuiteActiveSuiteSelector(state),
    activeSuiteMode: getSuiteActiveSuiteModeSelector(state),
  }
}

const mapDispatchToProps = dispatch => {
  return {
    setSuiteActiveSuite: suite => dispatch(genSuiteSetActiveSuite(suite)),
    getAllSuitesOfPage: (page, signal) => getAllSuitesOfPage(page, { signal }),
  }
}

export const SuiteList = connect(maStateToProps, mapDispatchToProps)((props) => {
  const { activePage, setSuiteActiveSuite, forceReloadIndex,
    getAllSuitesOfPage, activeSuiteId, activeSuite, activeSuiteMode } = props
  const [loading, setLoading] = useState(true)
  const [dataSource, setDataSource] = useState([])
  const [filter, setFitler] = useState({ title: '', level: '' })

  const wrapOnSelectItem = useCallback(item => setSuiteActiveSuite(item), [])

  const onAdd = useCallback(() => {
    const toAddSuit = { id: genTempId(), mode: RecordMode.add, title: Msgs.NotSaved, level: '' }
    setDataSource(currentDataSource => [toAddSuit, ...currentDataSource])
    setSuiteActiveSuite(toAddSuit)
  }, [])

  const onClone = useCallback(() => {
    const toAddSuit = { ...activeSuite, id: activeSuite.acitveSuiteId, mode: RecordMode.add }
    setSuiteActiveSuite(toAddSuit)
  }, [activeSuite])

  useEffect(() => {
    return withSignal(signal => {
      setLoading(true)
      getAllSuitesOfPage(activePage, signal)
        .then((data = []) => {
          setLoading(false)
          setDataSource(data)
        }).catch(err => {
          setLoading(false)
          setDataSource([])
          notify(NotifyType.error, err)
        })
    }, () => setLoading(false))
  }, [activePage, forceReloadIndex])

  useEffect(() => {
    if (dataSource.length) {
      setSuiteActiveSuite(dataSource[0])
    } else {
      setSuiteActiveSuite({ id: '', title: '', level: '', mode: '' })
    }
  }, [dataSource])

  const ifMatchFilter = (suite, { title, level }) => (title ? suite.title.indexOf(title) >= 0 : true) && (level ? suite.level === level : true)
  const visibleSuites = dataSource.filter(suite => ifMatchFilter(suite, filter))      // 最终显示的 suite

  const getTitle = useCallback(item => item.title, [])
  const getLevel = useCallback(item => item.level, [])

  const cloneAvalibale = activeSuiteId && activeSuiteMode === RecordMode.edit

  const onChangeFilter = useCallback((field, value) => setFitler(currentFilter => ({ ...currentFilter, [field]: value })), [])

  const onChangeFilterTitle = useCallback(title => onChangeFilter('title', title), [])
  const onChangeFilterLevel = useCallback(level => onChangeFilter('level', level.code), [])

  return loading
    ? <div className={basicStyle.basic_loading} />
    : <React.Fragment>
      <ColHeader title='所选页面用例：' />
      <div className={basicStyle.actions}>
        <button onClick={activePage ? onAdd : null} className={mergeStyle(basicStyle, classnames({ disabled: !activePage }))}>新增</button>
        <button onClick={cloneAvalibale ? onClone : null} className={mergeStyle(basicStyle, classnames({ disabled: !cloneAvalibale }))}>复制</button>
      </div>

      <div>
        <Input placeholder='筛选标题' value={filter.title} onChange={onChangeFilterTitle} readOnly={false} />
        <SuiteLevelSelector showNoLimitItem={true} initValue={filter.level} onSelectItem={onChangeFilterLevel} readOnly={false} />
      </div>

      {dataSource.length
        ? <SingleSelectableList activeValue={activeSuiteId} dataSource={visibleSuites}
          getItemValue={item => item.id || item.suiteId} getItemTitle={getTitle}
          getItemTitle2={getLevel} onSelectItem={wrapOnSelectItem} />
        : <EmptyElement />}
    </React.Fragment>
})